import convert from 'xml-js'
import init, { RsCore, create_new_info } from "../libs/petlib"
import ImgText from "../base/img_text";
import Scene from "./scene";
import { accAdd, accSub, winH, winW } from "../libs/utils";
import Img from "../base/img";
import { Rect } from "../base/shape";
import Text from "../base/text";
import Block from "../base/block";
import { PageStatus } from "../page_status";
import DataBus from "../databus";

const wasmPet = init("js/libs/petlib_bg.wasm")
const LogicCTX = canvas.getContext('2d')
const FS = wx.getFileSystemManager()
export const LogicDebugMode = true

//               [31, 29, 31, 30,  31,  30,  31,  31,  30,  31,  30,  31];
const MonthDays = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]

export function readFile(filePath) {
    var resStr
    try { var resStr = FS.readFileSync(filePath, 'utf8', 0) }
    catch (e) { console.error(e) }
    return resStr
}

function csv2JSON(csv) {
    var lines = csv.split("\n");
    var result = [];
    var headers = lines[0].split(",");

    for (var i = 1; i < lines.length; i++) {
        var obj = {};
        var currentline = lines[i].split(",");
        for (var j = 0; j < headers.length; j++) {
            obj[headers[j]] = currentline[j];
        }
        result.push(obj);
    }
    return JSON.stringify(result);
}

function sleep(time) {
    return new Promise(function (resolve) {
        setTimeout(resolve, time);
    });
}

let instance;

export default class JsLogic extends Scene {
    constructor(isDebugMode) {
        super(0, 0, winW, winH);
        if (instance) return instance
        instance = this

        this.reset()
        this.line = ""
        this.isDebugMode = isDebugMode
        this.bInitDone = false
        this.isNewUser = true
        this.info = {}
        this.bGetInfoDone = false
        this.chargeNumber = 500;
        this.timeNumber = 1.0;
        this.chargeDialog = null;
        this.timeDialog = null;
        this.databus = new DataBus();
    }
    loadRustLogic(callback){
        let str_pl = readFile("data/TravelCat - RightProvinceLink.csv")
        let str_tl = readFile("data/TravelCat - RightTransportLink.csv")
        let str_s = readFile("data/TravelCat - RightScenery.csv")
        let str_el = readFile("data/TravelCat - EconomyLevel.csv")

        var client_second = this.getClientSecond()
        wasmPet.then(() => {
            if (this.isNewUser) {
                this.info = create_new_info(this.line, client_second)
            }
            this.rsCore = new RsCore(this.info)
            this.rsCore.reset(str_pl, str_tl, str_s, str_el)
            this.step()
            this.bInitDone = true
            // this.loadSub();
            // callback(true);
        })

    }
    reset() {
        // this.getInfo()

        let xmlStr1 = readFile("fgui/logic_test/assets/Package1/MainScene.xml")
        this.mainScene = convert.xml2js(xmlStr1, { compact: true, spaces: 4 });

        let xmlStr2 = readFile("fgui/logic_test/assets/Package1/LogicTest.xml")
        this.LogicTest = convert.xml2js(xmlStr2, { compact: true, spaces: 4 });
    }

    update(frame) {
        if (this.bGetInfoDone && this.line) {

            this.bGetInfoDone = false
// debugger
            console.log("Get info down, frame: ", frame)

            this.loadRustLogic();
            // let str_pl = readFile("data/TravelCat - RightProvinceLink.csv")
            // let str_tl = readFile("data/TravelCat - RightTransportLink.csv")
            // let str_s = readFile("data/TravelCat - RightScenery.csv")
            // let str_el = readFile("data/TravelCat - EconomyLevel.csv")
            // var client_second = this.getClientSecond()
            // wasmPet.then(() => {
            //     if (this.isNewUser) {
            //         this.info = create_new_info(this.line, client_second)
            //     }
            //     this.rsCore = new RsCore(this.info)
            //     this.rsCore.reset(str_pl, str_tl, str_s, str_el)
            //     this.step()
            //     this.bInitDone = true
            //     // debugger
            // })
        }

        if (this.bInitDone) {
            if (frame % 100 == 99) {
                this.step()
            }
        }
    }

    reapFish() {
        this.logicCheck()
        var reapSuc = this.rsCore.reap_fish()
        return reapSuc
    }

    step() {
        // debugger
        var client_second_last = this.rsCore.get_client_second()
        var client_second = this.getClientSecond()
        var time = (client_second - client_second_last) / 3600

        this.rsCore.step(time)
        this.rsCore.set_client_second(client_second)
        this.info = this.rsCore.get_info_rs()
        this.setInfoToStorage(this.info)
    }

    getClientSecond() {
        var date = new Date();
        var month = date.getMonth()
        var day = date.getDate()
        var hour = date.getHours()
        var minute = date.getMinutes()
        var second = date.getSeconds()
        var res = (MonthDays[month] + day) * 24 * 3600 + hour * 3600 + minute * 60 + second
        return res
    }

    updateTime(time) {
        this.logicCheck()
        this.rsCore.step(time)
        this.setInfoToStorage(this.info)
    }

    giveMoneyToCat(money) {
        this.logicCheck()
        this.rsCore.cat_receive_money(money)
        this.info = this.rsCore.get_info_rs()
        this.setInfoToStorage(this.info)
        this.subUserMoney(money)
    }

    subUserMoney(money) {
        this.logicCheck()
        this.rsCore.user_sub_money(money)
        this.info = this.rsCore.get_info_rs()
        this.setInfoToStorage(this.info)
    }

    addUserMoney(money) {
        this.logicCheck()
        this.rsCore.user_add_money(money)
        this.info = this.rsCore.get_info_rs()
        this.setInfoToStorage(this.info)
    }

    getPassingPids() {
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return this.info.hist.passing_pids
    }
    getCurSidName() {
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return this.info.show.cur_sid_name
    }

    /**
     * 当前旅行状态
     * @returns {*}
     */
    getTravelType(){
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return this.info.state.travel_type
    }

    /**
     * 当前猫罐头状态
     */
    getCansStatus(){
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return this.info.base.is_fish_ripe;
    }
    /**
     * 玩家当前持有的货币数量
     */
    getUserMoney(){
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return this.info.base.user_money;
    }
    getCurrentPid() {
        this.logicCheck()
        this.info = this.rsCore.get_info_rs()
        return  this.info.state.pid;
    }

    getPlayedIdsByPid(pid) {
        this.logicCheck()
        return this.rsCore.get_played_sids_by_pid(pid)
    }

    logicCheck() {
        if (this.bInitDone == false) {
            console.error("[logicCheak], wrong logic !")
        }
    }

    setInfoToStorage(data) {
        wx.setStorage({
            key: "info",
            data: data,
            encrypt: false,
            success(res) {
            },
            fail() {
                console.log("setInfo fail")
            }
        })
    }

    render(ctx) {
        if (this.databus.gameStatus !== PageStatus.LogicTest) {
            return;
        }

        if (this.bInitDone) {
            LogicCTX.clearRect(0, 0, canvas.width, canvas.height)

            var graphs = this.LogicTest.component.displayList.graph
            var texts = this.LogicTest.component.displayList.text


            graphs.forEach((v, i) => {
                var graph_attr = v._attributes
                var name = graph_attr.name
                var [w, h] = graph_attr.size.split(",");
                var [x, y] = graph_attr.xy.split(",");
                LogicCTX.fillStyle = graph_attr.fillColor;
                LogicCTX.fillRect(x, y, w, h)
            })

            texts.forEach((v, i) => {
                var text_attr = v._attributes
                var [w, h] = text_attr.size.split(",");
                var [x, y] = text_attr.xy.split(",");
                LogicCTX.fillStyle = "#000000";
                LogicCTX.font = text_attr.fontSize.concat('px Arial')

                if (text_attr.name == "game_time_k") {
                    LogicCTX.fillText("游戏时长: ", x, y, w)
                }
                if (text_attr.name == "game_time_v") {
                    LogicCTX.fillText(this.info.base.game_time, x, y, w)
                }

                if (text_attr.name == "cur_pid_name_k") {
                    LogicCTX.fillText("当前省份: ", x, y, w)
                }
                if (text_attr.name == "cur_pid_name_v") {
                    LogicCTX.fillText(this.info.show.cur_pid_name, x, y, w)
                }

                if (text_attr.name == "passing_pid_names_k") {
                    LogicCTX.fillText("已玩省份: ", x, y, w)
                }
                if (text_attr.name == "passing_pid_name_v") {
                    LogicCTX.fillText(this.info.show.passing_pid_names, x, y, w)

                }

                if (text_attr.name == "travel_type_k") {
                    LogicCTX.fillText("旅行状态: ", x, y, w)
                }
                if (text_attr.name == "travel_type_v") {
                    LogicCTX.fillText(this.info.state.travel_type, x, y, w)
                }

                if (text_attr.name == "time_k") {
                    LogicCTX.fillText("状态时间: ", x, y, w)
                }
                if (text_attr.name == "time_v") {
                    LogicCTX.fillText(this.info.state.time, x, y, w)
                }

                if (text_attr.name == "user_money_k") {
                    LogicCTX.fillText("玩家金钱: ", x, y, w)
                }
                if (text_attr.name == "user_money_v") {
                    LogicCTX.fillText(this.info.base.user_money, x, y, w)
                }

                if (text_attr.name == "economy_level_k") {
                    LogicCTX.fillText("猫咪经济: ", x, y, w)
                }
                if (text_attr.name == "economy_level_v") {
                    LogicCTX.fillText(this.info.show.cur_el_name, x, y, w)
                }

                if (text_attr.name == "cat_money_k") {
                    LogicCTX.fillText("猫咪金钱: ", x, y, w)
                }
                if (text_attr.name == "cat_money_v") {
                    LogicCTX.fillText(this.info.base.cat_money, x, y, w)
                }

                if (text_attr.name == "cur_sid_name_k") {
                    LogicCTX.fillText("当前景点: ", x, y, w)
                }
                if (text_attr.name == "cur_sid_name_v") {
                    LogicCTX.fillText(this.info.show.cur_sid_name, x, y, w)
                }

                if (text_attr.name == "plan_sids_k") {
                    LogicCTX.fillText("景点计划: ", x, y, w)
                }
                if (text_attr.name == "plan_sids_v") {
                    LogicCTX.fillText(this.info.plan.plan_sids, x, y, w)
                }

                if (text_attr.name == "total_played_sids_k") {
                    LogicCTX.fillText("已玩景点: ", x, y, w)
                }
                if (text_attr.name == "total_played_sids_v") {
                    LogicCTX.fillText(this.info.hist.total_played_sids, x, y, w)
                }

                if (text_attr.name == "total_played_sid_names_k") {
                    LogicCTX.fillText("已玩景点: ", x, y, w)
                }
                if (text_attr.name == "total_played_sid_names_v") {
                    LogicCTX.fillText(this.info.show.total_played_sid_names, x, y, w)
                }
            })
        }
        super.render(ctx)
    }

    initView(ctx) {
        super.initView(ctx);
        var btnCharge = new ImgText('js/sub/images/btn_guanqia.png', 20, 740, 70, 60, 70, 60, "打钱");

        btnCharge.bindClickEvent(() => {
            /// 可以输入金额
            /// 发送按键
            this.addChargeDialog(ctx);
        });
        this.addChild(btnCharge)

        var onlineTime = new ImgText('js/sub/images/btn_guanqia.png', 120, 740, 70, 60, 70, 60, "上线");

        onlineTime.bindClickEvent(() => {
            /// 输入时间
            /// 发送按键
            this.addTimeDialog(ctx);
        });
        this.addChild(onlineTime)

        var backImg = new Img("js/sub/images/icon_back.png", 10, 20, 40, 40);
        backImg.bindClickEvent(() => {
            this.backPage();
        });
        this.addChild(backImg, 'backImg')
    }
    backPage() {
        super.backPage();
        this.hideAllDialog()
        let databus = new DataBus()
        wx.getStorage({
            key:"lastPage",
            encrypt: false,
            success: res => {
                console.log("xxxxx getInfo suc")
                if(res.data === PageStatus.GameMainMenu){
                    databus.gameStatus = PageStatus.GameMainMenu
                }else {
                    databus.gameStatus = PageStatus.TripShow
                }
            },
            fail: () => {
                console.log("xxxxx getInfo fail")
                databus.gameStatus = PageStatus.GameMainMenu
            }
        })
    }

    addChargeDialog(ctx) {
        this.hideTimeDialog()
        if (this.chargeDialog !== null) {
            return
        }
        var dialog = new Block(20, winH / 2 - 40, winW - 40, 60);
        this.chargeDialog = dialog;


        var rect = new Rect(20, winH / 2 - 40, winW - 40, 60, 10);
        rect.bgColor = 'white';

        var img1 = new Img("js/sub/images/icon_add.webp", 40, winH / 2 - 30, 40, 40);
        var img2 = new Img("js/sub/images/icon_subtract.webp", 140, winH / 2 - 30, 40, 40);
        var text = new Text(this.chargeNumber, 90, winH / 2 - 20, 20);
        var sendText = new Text("发送金额", winW - 150, winH / 2 - 20, 20);
        sendText.bgColor = 'lightBlue';
        this.addChild(dialog, "dialog")
        dialog.addChild(rect, "rect")
        dialog.addChild(img1, "img1")
        dialog.addChild(img2, "img2")
        dialog.addChild(text, "text")
        dialog.addChild(sendText, "sendText")
        this.drawToCanvas(ctx)


        img1.bindClickEvent(() => {
            this.chargeNumber += 500;
            text.text = this.chargeNumber;
        })
        img2.bindClickEvent(() => {
            this.chargeNumber -= 500;
            if (this.chargeNumber <= 0) {
                this.chargeNumber = 0;
            }
            text.text = this.chargeNumber;
        })

        sendText.bindClickEvent(() => {
            wx.showToast({
                title: `充值金额 ${this.chargeNumber}`,
            });
            this.giveMoneyToCat(this.chargeNumber)

            this.hideAllDialog();
        })
    }
    hideTimeDialog() {

        if (this.timeDialog !== null) {
            this.removeChild(this.timeDialog)
            this.timeDialog = null;
            this.timeNumber = 5.0;
        }

    }
    hideChargeDialog() {
        if (this.chargeDialog !== null) {
            this.removeChild(this.chargeDialog)
            this.chargeDialog = null;
            this.chargeNumber = 500;
        }

    }
    hideAllDialog() {

        if (this.chargeDialog !== null) {
            this.removeChild(this.chargeDialog)
            this.chargeDialog = null;
            this.chargeNumber = 500;
        }
        if (this.timeDialog !== null) {
            this.removeChild(this.timeDialog)
            this.timeDialog = null;
            this.timeNumber = 1.0;
        }

    }
    addTimeDialog(ctx) {
        this.hideChargeDialog()
        if (this.timeDialog !== null) {
            debugger
            return
        }
        this.timeDialog = true;

        var dialog = new Block(20, winH / 2 - 40, winW - 40, 60);
        this.timeDialog = dialog;
        var rect = new Rect(20, winH / 2 - 40, winW - 40, 60, 10);
        rect.bgColor = 'white';

        var img1 = new Img("js/sub/images/icon_add.webp", 40, winH / 2 - 30, 40, 40);
        var img2 = new Img("js/sub/images/icon_subtract.webp", 140, winH / 2 - 30, 40, 40);

        var text = new Text(this.timeNumber, 90, winH / 2 - 20, 20);
        var sendText = new Text("发送时间", winW - 150, winH / 2 - 20, 20);
        sendText.bgColor = 'lightBlue';
        this.addChild(dialog, "dialog")
        dialog.addChild(rect, "rect")
        dialog.addChild(img1, "img1")
        dialog.addChild(img2, "img2")
        dialog.addChild(text, "text")
        dialog.addChild(sendText, "sendText")
        this.drawToCanvas(ctx)

        img1.bindClickEvent(() => {
            this.timeNumber = accAdd(this.timeNumber, 0.5);

            text.text = this.timeNumber;
        })
        img2.bindClickEvent(() => {

            this.timeNumber = accSub(this.timeNumber, 0.5);
            if (this.timeNumber <= 0) {
                this.timeNumber = 0;
            }
            text.text = this.timeNumber;
        })

        sendText.bindClickEvent(() => {
            wx.showToast({
                title: `发送时间 ${this.timeNumber}`,
            });
            this.updateTime(this.timeNumber)

            this.hideAllDialog();
        })
    }
}
